package collections;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.google.common.base.Objects;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;

public class MultiMapDemo {
	
	private static Contact[] contacts;
	private static Group[] groups;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		initData();
		//将联系人按照他们的分组分类
		
		//老办法
//		HashMap<String, List<Contact>> groupsContactsOld = oldMethod();
//		System.out.println(groupsContactsOld);
		
		Multimap<Group, Contact> groupsContacts = newMethodUseMultimap();
		System.out.println(groupsContacts);
		Collection<Contact> cts = groupsContacts.get(groups[0]);
		System.out.println(cts);
		//包含了重复出现的所有contact
		Collection<Contact> values = groupsContacts.values();
		System.out.println(values);
		//任意一个key对应的list包含value即返回true
		boolean b = groupsContacts.containsValue(contacts[0]);
		System.out.println(b);
		//得到所有重复现象的contact个数
		System.out.println(groupsContacts.size());
		
		//得到的是包含group重复出现次数的集合
		Multiset<Group> keys = groupsContacts.keys();
		for (Group group : keys) {
			System.out.print(group+"\t");
		}
		System.out.println();
		Collection<Entry<Group, Contact>> entries = groupsContacts.entries();
		System.out.println(entries);
		//想得到不重复的group集合，用asMap转换成map后操作
		Map<Group, Collection<Contact>> asMap = groupsContacts.asMap();
		System.out.println(asMap.keySet());
		asMap.clear();
		//会影响到源集合
		System.out.println(groupsContacts);
	}
	
	public static HashMap<String, List<Contact>> oldMethod() {
		HashMap<String, List<Contact>> groupsContacts=Maps.newHashMap();
		for (Contact contact : contacts) {
			for (Group group : contact.groups) {
				List<Contact> list = groupsContacts.get(group.name);
				if (list==null) {
					list=Lists.newArrayList();
					groupsContacts.put(group.name, list);
				}
				list.add(contact);
			}
		}
		return groupsContacts;
	}
	
	public static Multimap<Group, Contact> newMethodUseMultimap() {
		Multimap<Group, Contact> groupsContacts=ArrayListMultimap.create();
		for (Contact contact : contacts) {
			for (Group group : contact.groups) {
				groupsContacts.put(group, contact);
			}
		}
		return groupsContacts;
	}
	
	private static void initData() {
		Group g1 = new Group("1", "小学同学");
		Group g2 = new Group("2", "初中同学");
		Group g3 = new Group("3", "高中同学");
		Group g4 = new Group("4", "大学同学");
		Group g5 = new Group("5", "研究生同学");
		Group g6 = new Group("6", "博士同学");
		
		groups = new Group[]{g1,g2,g3,g4,g5,g6};
		
		Contact c1=new Contact("1", "张三");
		c1.addGroup(g1,g2,g3);
		
		Contact c2=new Contact("2", "李四");
		c2.addGroup(g2,g3,g4);
		
		Contact c3=new Contact("3", "王五");
		c3.addGroup(g4);
		
		Contact c4=new Contact("4", "赵六");
		c4.addGroup(g4,g5);
		
		Contact c5=new Contact("5", "马七");
		c5.addGroup(g5);
		
		Contact c6=new Contact("6", "冯八");
		c6.addGroup(g1,g5);
		
		Contact c7=new Contact("7", "郭九");
		c7.addGroup(g3,g4);
		
		contacts = new Contact[]{
				c1,c2,c3,c4,c5,c6,c7
		};
	}
	
	public static class Group{
		public String id;
		public String name;
		
		public Group() {
		}

		public Group(String id, String name) {
			this.id = id;
			this.name = name;
		}
		
		@Override
		public int hashCode() {
			return Objects.hashCode(id,name);
		}
		
		@Override
		public boolean equals(Object obj) {
			return Objects.equal(this, obj);
		}
		
		@Override
		public String toString() {
			return Objects.toStringHelper(this)
					.add("id", id)
					.add("name", name)
					.toString();
		}
	}
	
	public static class Contact{
		public String id;
		public String name;
		public Set<Group> groups=Sets.newHashSet();
		
		public Contact() {
		}

		public Contact(String id, String name) {
			this.id = id;
			this.name = name;
		}
		
		public void addGroup(Group ... inGroups){
			for (Group group:inGroups) {
				groups.add(group);
			}
		}
		
		@Override
		public int hashCode() {
			return Objects.hashCode(id,name);
		}
		
		@Override
		public boolean equals(Object obj) {
			return Objects.equal(this, obj);
		}
		
		@Override
		public String toString() {
			return Objects.toStringHelper(this)
					.add("id", id)
					.add("name", name)
					.toString();
		}
	}
}
